home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / demostu2 / texture1.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-12-07  |  10.8 KB  |  614 lines

  1. PROGRAM Texture1;
  2. {
  3.   Real Texture Mapping
  4.   - by Bjarke Viksφe
  5.   aug 1994
  6.  
  7.   Texture mapping done on a tweaked screen 320x200x256 !
  8.   Texture is 128x128 in 256 colours. File is 'marble.lbm'.
  9.   However, the texturebuffer is 256x256 for fast access!
  10.  
  11.   If it jerks on your (slower) computer try setting the BOX constant a
  12.   bit lower.
  13.  
  14. The texture inner loop looks like this:
  15.           ╔═════════════╦═══════════════════════════╗
  16.           ║ UPPER 16BIT ║        LOWER 16BIT        ║
  17. ╔═══════╬═════════════╬═════════════╦═════════════╣  Inner: add ecx,eax
  18. ║  REG  ║   HI WORD   ║   HI BYTE   ║   LO BYTE   ║         adc ebx,ebp
  19. ╠═══════╬═════════════╬═════════════╬═════════════╣         adc bh,dl
  20. ║  EAX  ║  X-INC LSW  ║     ---     ║     ---     ║         mov dh,[ds:bx]
  21. ╠═══════╬═════════════╬═════════════╬═════════════╣         mov [es:di],dh
  22. ║  ECX  ║  TXT-X LSW  ║     ---     ║  LOOPCOUNT  ║         add di,80
  23. ╠═══════╬═════════════╬═════════════╬═════════════╣         loop Inner
  24. ║  EDX  ║     ---     ║ TEXTUREDATA ║    Y-INC    ║
  25. ╠═══════╬═════════════╬═════════════╬═════════════╣
  26. ║  EBP  ║  Y-INC LSW  ║ X-INC  SIGN ║    X-INC    ║
  27. ╠═══════╬═════════════╬═════════════╬═════════════╣
  28. ║  EBX  ║  TXT-Y LSW  ║  TEXTURE Y  ║  TEXTURE X  ║
  29. ╚═══════╩═════════════╩═════════════╩═════════════╝
  30. (Rest easy, this is not something I just figured out. I peeked at some
  31.  code from a dude called Fantom/UBP. Also read the PCGPE. It has great
  32.  articles about texture mapping!)
  33. }
  34.  
  35. {$A+,B-,G+,E+,I+,N-,X+}
  36. {$C FIXED PRELOAD PERMANENT}
  37.  
  38. {$DEFINE DEBUG}
  39.  
  40. USES
  41.     DEMOINIT,ILBM256,PICTURE;
  42.  
  43. CONST
  44.     NUMBER_FACES = 6;
  45.     NUMBER_COORDS = 8;
  46.     BOX = 110; {size of box}
  47.  
  48. TYPE
  49.     SlopeType = array[0..319*2] of integer;
  50.  
  51.     FaceType = RECORD
  52.         l1,l2,l3,l4 : byte;
  53.     end;
  54.  
  55.  
  56. VAR
  57.     slope,textureslope : SlopeType;
  58.     face : array[1..NUMBER_FACES] of FaceType;
  59.     cbuffer : array[0..NUMBER_COORDS*2-1] of integer;
  60.  
  61.     minx,maxx : integer;
  62.  
  63.     sinustabel : array[0..639] of integer;
  64.     v1,v2,v3 : word; {rotation angle}
  65.     cos1,sin1,cos2,sin2,cos3,sin3 : integer;
  66.  
  67.     texture : pScreen;
  68.  
  69.  
  70. CONST
  71.     display1 : word = $0000;
  72.     display2 : word = $4000;
  73.     {setup coords for a box}
  74.     coords : array[0..NUMBER_COORDS*3-1] of integer =
  75.         (box,box,-box, -box,box,-box, -box,-box,-box, box,-box,-box,
  76.         box,box,box, -box,box,box, -box,-box,box, box,-box,box);
  77.  
  78.  
  79. (*------------------------------------------------*)
  80.  
  81. procedure SetupSinus;
  82. var
  83.     i : integer;
  84.     v, vadd : real;
  85. begin
  86.     v:=0.0;
  87.     vadd:=(2.0*pi/512.0);
  88.     for i:=0 to 639 do begin
  89.         sinustabel[i]:=round(sin(v)*32767);
  90.         v:=v+vadd;
  91.     end;
  92. end;
  93.  
  94. procedure SetupFaces;
  95. {setup faces. Make sure face keeps track of which coordinates it uses!}
  96. begin
  97.     with face[1] do begin l1:=3; l2:=2; l3:=1; l4:=0; end;
  98.     with face[2] do begin l1:=4; l2:=5; l3:=6; l4:=7; end;
  99.     with face[3] do begin l1:=0; l2:=1; l3:=5; l4:=4; end;
  100.     with face[4] do begin l1:=1; l2:=2; l3:=6; l4:=5; end;
  101.     with face[5] do begin l1:=2; l2:=3; l3:=7; l4:=6; end;
  102.     with face[6] do begin l1:=3; l2:=0; l3:=4; l4:=7; end;
  103. end;
  104.  
  105. procedure InitDemo;
  106. var
  107.     i,j,k : word;
  108. begin
  109.     Screen_Off;
  110.     ClearWholeScreen;
  111.     SetupSinus;
  112.     SetupFaces;
  113.  
  114.     New(texture);    {load picture}
  115.     LoadPix(texture,'marble.lbm');
  116.     j:=0; k:=0;
  117.     {picture is 320x200. Need to convert it to 256x128}
  118.     for i:=1 to 128 do begin
  119.         Move(texture^[j],texture^[k],128);
  120.         inc(j,320);
  121.         inc(k,256);
  122.     end;
  123.     SetCMAP;
  124.  
  125.     v1:=0; v2:=0; v3:=0;
  126.  
  127.     Screen_On;
  128. end;
  129.  
  130. procedure UninitDemo;
  131. begin
  132.     Dispose(texture);
  133. end;
  134.  
  135.  
  136. (*------------------------------------------------*)
  137.  
  138. procedure SwapDisplay;
  139. var
  140.     temp : word;
  141. begin
  142.     temp:=display2;
  143.     display2:=display1;
  144.     display1:=temp;
  145.     SetAddress(Ptr(SEGA000,display2));
  146. end;
  147.  
  148. procedure ClearScreen; assembler;
  149. asm
  150.     mov    dx,$3C4
  151.     mov    ax,$0F02
  152.     out    dx,ax
  153.  
  154.     mov    es,SEGA000
  155.     mov    di,display1
  156.     add    di,(30*WIDTH)+16
  157.     mov    dx,140
  158.     xor ax,ax
  159.     mov    bx,48/2
  160. @loop:
  161.     mov    cx,bx
  162.     rep stosw
  163.     add    di,WIDTH-48
  164.     dec    dl
  165.     jnz    @loop
  166. end;
  167.  
  168.  
  169. (*------------------------------------------------*)
  170.  
  171. procedure ClearSlope; assembler;
  172. asm
  173.     mov    ax,ds
  174.     mov    es,ax
  175.     lea    di,slope
  176.     DB LONG; mov ax,$8000; DW $8000;
  177.     cld
  178.     mov    cx,TYPE(slopetype)/4
  179.     rep; DB LONG; stosw
  180. end;
  181.  
  182. procedure CalcSlope(l1,l2 : integer; tex1a,tex1b,tex2a,tex2b : word); assembler;
  183. var
  184.     tex1add,tex2add : word;
  185.     xlowadd,xhighadd : word;
  186.     ysize : integer;
  187. asm
  188.     lea    si,cbuffer
  189.     DB LONG; xor cx,cx
  190.     mov    bx,l1                    {get first coords}
  191.     shl    bx,2
  192.     mov    dx,[si+bx]            {get x/y coords}
  193.     mov    cx,[si+bx+2]
  194.  
  195.     mov    ax,l2                    {get second coords}
  196.     shl    ax,2
  197.     add    si,ax
  198.     mov    ax,[si]                {get x/y coords}
  199.     mov    bx,[si+2]
  200.  
  201.     cmp    bx,cx                    {make sure we go downwards...}
  202.     jle    @noswap
  203.     mov    si,tex1a                {swap texture x}
  204.     xchg    tex1b,si
  205.     mov    tex1a,si
  206.     mov    si,tex2a                {swap texture y}
  207.     xchg    tex2b,si
  208.     mov    tex2a,si
  209.     xchg    ax,dx                    {swap x}
  210.     xchg    bx,cx                    {sway y}
  211. @noswap:
  212.  
  213.     cmp    bx,minx                {record miny and maxy}
  214.     jge    @minx
  215.     mov    minx,bx
  216. @minx:
  217.     cmp    cx,maxx
  218.     jle    @maxx
  219.     mov    maxx,cx
  220. @maxx:
  221.  
  222.     sub    cx,bx
  223.     and    cx,cx
  224.     jnz    @notzero
  225.     jmp    @zero
  226. @notzero:
  227.     mov    ysize,cx
  228.     add    bx,bx
  229.     add    bx,bx
  230.     lea    si,slope
  231.     add    si,bx
  232.  
  233.     push    ax
  234.     sub    dx,ax
  235.     inc    dx
  236.  
  237.     mov    ax,dx
  238.     DB LONG; shl    ax,16
  239.     {cdq} DB $66,$99
  240.     DB LONG; idiv    cx
  241.     DB LONG; mov    dx,ax
  242.     DB LONG; shr    dx,16
  243.     mov    xlowadd,ax
  244.     mov    xhighadd,dx
  245.  
  246.     mov    al,BYTE PTR tex1a
  247.     mov    ah,BYTE PTR tex1b
  248.     sub    ah,al
  249.     xor    al,al
  250.     cwd
  251.     idiv    cx
  252.     mov    tex1add,ax
  253.  
  254.     mov    al,BYTE PTR tex2a
  255.     mov    ah,BYTE PTR tex2b
  256.     sub    ah,al
  257.     xor    al,al
  258.     cwd
  259.     idiv    cx
  260.     mov    tex2add,ax
  261. @one:
  262.     pop    cx
  263.  
  264.     xor    bx,bx
  265.     mov    ah,BYTE PTR tex1a
  266.     xor    al,al
  267.     mov    dh,BYTE PTR tex2a
  268.     xor    dl,dl
  269.     mov    di,$8000
  270. @loop:
  271.     cmp    [si],di
  272.     jne    @other
  273.     mov    [si],cx
  274.     mov    [si+TYPE(SlopeType)],ah
  275.     mov    [si+TYPE(SlopeType)+1],dh
  276.     add    si,4
  277.     add    bx,xlowadd
  278.     adc    cx,xhighadd
  279.     add    ax,tex1add
  280.     add    dx,tex2add
  281.     dec    ysize
  282.     jnz    @loop
  283.     jmp    NEAR PTR @zero
  284. @other:
  285.     mov    [si+2],cx
  286.     mov    [si+TYPE(SlopeType)+2],ah
  287.     mov    [si+TYPE(SlopeType)+3],dh
  288.     add    si,4
  289.     add    bx,xlowadd
  290.     adc    cx,xhighadd
  291.     add    ax,tex1add
  292.     add    dx,tex2add
  293.     dec    ysize
  294.     jnz    @loop
  295. @zero:
  296. end;
  297.  
  298.  
  299. (*------------------------------------------------*)
  300.  
  301. procedure CalcAngle;
  302. begin
  303.     sin1:=sinustabel[v1]; cos1:=sinustabel[v1+128];
  304.     sin2:=sinustabel[v2]; cos2:=sinustabel[v2+128];
  305.     sin3:=sinustabel[v3]; cos3:=sinustabel[v3+128];
  306.     v1:=(v1+2) AND 511;
  307.     v2:=(v2-1) AND 511;
  308.     v3:=(v3+1) AND 511;
  309. end;
  310.  
  311. procedure RotateAllCoords; assembler;
  312. {Rotate all coords in "coords" around all 3 axis and make
  313.  perspective calcualtion. Store x,y,z results in "cbuffer"}
  314. var
  315.     xkoord,ykoord,zkoord, n : integer;
  316. asm
  317.     mov    ax,ds
  318.     mov    es,ax
  319.     lea    si,coords
  320.     lea    di,cbuffer
  321.     mov    n,NUMBER_COORDS
  322.     cld
  323. @loop:
  324.     lodsw
  325.     mov    xkoord,ax
  326.     lodsw
  327.     mov    ykoord,ax
  328.     lodsw
  329.     mov    zkoord,ax
  330.  
  331.     mov    ax,xkoord               {rotate around Z-axis}
  332.     push    ax
  333.     imul    Cos1
  334.     add    ax,ax
  335.     adc    dx,dx
  336.     mov    bx,dx
  337.     mov    ax,ykoord
  338.     imul    Sin1
  339.     add    ax,ax
  340.     adc    dx,dx
  341.     sub    bx,dx
  342.     mov    xkoord,bx
  343.     pop    ax
  344.     imul    Sin1
  345.     add    ax,ax
  346.     adc    dx,dx
  347.     mov    bx,dx
  348.     mov    ax,ykoord
  349.     imul    Cos1
  350.     add    ax,ax
  351.     adc    dx,dx
  352.     add    bx,dx
  353.     mov    ykoord,bx
  354.  
  355.     mov    ax,ykoord               {rotate around Y-axis}
  356.     push    ax
  357.     imul    Cos2
  358.     add    ax,ax
  359.     adc    dx,dx
  360.     mov    bx,dx
  361.     mov    ax,zkoord
  362.     imul    Sin2
  363.     add    ax,ax
  364.     adc    dx,dx
  365.     sub    bx,dx
  366.     mov    ykoord,bx
  367.     pop    ax
  368.     imul    Sin2
  369.     add    ax,ax
  370.     adc    dx,dx
  371.     mov    bx,dx
  372.     mov    ax,zkoord
  373.     imul    Cos2
  374.     add    ax,ax
  375.     adc    dx,dx
  376.     add    bx,dx
  377.     mov    zkoord,bx
  378.  
  379.     mov    ax,xkoord               {rotate around X-axis}
  380.     push    ax
  381.     imul    Cos3
  382.     add    ax,ax
  383.     adc    dx,dx
  384.     mov    bx,dx
  385.     mov    ax,zkoord
  386.     imul    Sin3
  387.     add    ax,ax
  388.     adc    dx,dx
  389.     sub   bx,dx
  390.     mov    xkoord,bx
  391.     pop    ax
  392.     imul    Sin3
  393.     add    ax,ax
  394.     adc    dx,dx
  395.     mov    bx,dx
  396.     mov    ax,zkoord
  397.     imul    Cos3
  398.     add    ax,ax
  399.     adc    dx,dx
  400.     add    bx,dx
  401.     mov    zkoord,bx
  402.  
  403.     add    bx,800
  404.     and    bx,bx
  405.     jnz    @zero
  406.     mov    bl,1
  407. @zero:
  408.  
  409.     mov    ax,xkoord
  410.     cwd
  411.     mov    dl,ah
  412.     mov    ah,al
  413.     xor    al,al
  414.     idiv    bx
  415.     add    ax,100
  416.     stosw
  417.  
  418.     mov    ax,ykoord
  419.     cwd
  420.     mov    dl,ah
  421.     mov    ah,al
  422.     xor    al,al
  423.     idiv    bx
  424.     add    ax,160
  425.     stosw
  426.  
  427.     dec    n
  428.     jnz    @loop
  429. end;
  430.  
  431.  
  432.  
  433. function FaceShown(l1,l2,l3 : word) : boolean;
  434. var
  435.     a,b : longint;
  436. begin
  437.     a := longmul(cbuffer[l1]-cbuffer[l2],cbuffer[l3+1]-cbuffer[l2+1]);
  438.     b := longmul(cbuffer[l1+1]-cbuffer[l2+1],cbuffer[l3]-cbuffer[l2]);
  439.     FaceShown := (a-b) > 0;
  440. end;
  441.  
  442.  
  443. procedure FillShape(x,xsize : integer); assembler;
  444. var
  445.     tex1,tex2 : word;
  446.     xlowadd,xhighadd,ylowadd,yhighadd : word;
  447.     loops : word;
  448. asm
  449.     cmp    xsize,320
  450.     jb        @drawit
  451.     jmp    @done
  452. @drawit:
  453.     mov    di,display1
  454.     mov    ax,x
  455.     shr    ax,2
  456.     add    di,ax
  457.  
  458.     lea    si,slope
  459.     mov    ax,x
  460.     shl    ax,2
  461.     add    si,ax
  462.  
  463.     mov    es,SEGA000
  464.     cld
  465. @xloop:
  466.     mov    cx,x
  467.     and    cl,3
  468.     mov    al,1
  469.     shl    al,cl
  470.     mov    ah,al
  471.     mov    dx,$3C4
  472.     mov    al,$02
  473.     out    dx,ax
  474.  
  475.     mov    cx,[si+TYPE(slopetype)] {fetch texture x,y values}
  476.     lodsw                                    {fetch first xpos}
  477.     mov    dx,ax
  478.     mov    bx,[si+TYPE(slopetype)] {fetch second texture values}
  479.     lodsw                                    {fetch second xpos}
  480.     cmp    ax,dx                            {need to go from left to right..}
  481.     jle    @exchange
  482.     xchg    ax,dx
  483.     xchg    cx,bx
  484. @exchange:
  485.     mov    tex1,cx
  486.     mov    tex2,bx
  487.  
  488.     push    si
  489.     push    di
  490.  
  491.     DB LONG; xor cx,cx
  492.     mov    cx,dx
  493.     sub    cx,ax
  494.     or        cx,cx
  495.     jnz    @y_is_great
  496.     jmp    @filledout
  497. @y_is_great:
  498.     add    ax,ax
  499.     mov    bx,ax
  500.     add    di,[OFFSET ytabel+bx]
  501.     mov    loops,cx
  502.  
  503.     push    ds
  504.  
  505.     mov    al,BYTE PTR tex1
  506.     sub    al,BYTE PTR tex2
  507.     cbw
  508.     DB LONG; shl    ax,16
  509.     {cdq} DB $66,$99
  510.     DB LONG; idiv    cx
  511.     DB LONG; mov    dx,ax
  512.     DB LONG; shr    dx,16
  513.     mov    xlowadd,ax
  514.     mov    xhighadd,dx
  515.  
  516.     mov    al,BYTE PTR tex1+1
  517.     sub    al,BYTE PTR tex2+1
  518.     cbw
  519.     DB LONG; shl    ax,16
  520.     {cdq} DB $66,$99
  521.     DB LONG; idiv    cx
  522.     DB LONG; mov    dx,ax
  523.     DB LONG; shr    dx,16
  524.     mov    ylowadd,ax
  525.     mov    yhighadd,dx
  526.  
  527.     DB LONG; xor dx,dx
  528.     mov    dx,yhighadd
  529.  
  530.     mov    ax,xlowadd
  531.     DB LONG; shl ax,16
  532.  
  533.     mov    bx,ylowadd
  534.     DB LONG; shl bx,16
  535.     mov    bx,xhighadd
  536.     DB LONG; mov si,bx
  537.  
  538.     DB LONG; xor bx,bx
  539.     mov    bl,BYTE PTR tex2
  540.     mov    bh,BYTE PTR tex2+1
  541.     DB LONG; xor cx,cx
  542.     mov    cx,loops
  543.     mov    ds,WORD PTR texture+2
  544. @loop:
  545.     DB LONG; add cx,ax
  546.     DB LONG; adc bx,si
  547.     adc    bh,dl
  548.     mov    dh,[bx]
  549.     mov    [es:di],dh
  550.     add    di,80
  551.     dec    cx
  552.     jnz    @loop
  553.  
  554.     pop    ds
  555.  
  556. @filledout:
  557.     pop    di
  558.     pop    si
  559. @filledout_fast:
  560.     inc   x
  561.     test    x,3
  562.     jnz    @no_address_add
  563.     inc    di
  564. @no_address_add:
  565.     dec    xsize
  566.     jnz    @xloop
  567. @done:
  568. end;
  569.  
  570.  
  571. procedure RunOnce;
  572. var
  573.     i : integer;
  574. begin
  575.     SwapDisplay;
  576.     VBLANK;
  577. {$IFDEF DEBUG}
  578.     SetRGB(0,16,0,0);
  579. {$ENDIF}
  580.  
  581.     ClearScreen;
  582.  
  583.     CalcAngle;
  584.     RotateAllCoords;
  585.  
  586.     for i:=1 to NUMBER_FACES do begin
  587.         with face[i] do if FaceShown(l1 SHL 1,l2 SHL 1,l3 SHL 1) then begin
  588.             ClearSlope;
  589.             minx := 320; maxx := 0;
  590.             CalcSlope(l1,l2, 0,0,127,0);
  591.             CalcSlope(l2,l3, 127,0,127,127);
  592.             CalcSlope(l3,l4, 127,127,0,127);
  593.             CalcSlope(l4,l1, 0,127,0,0);
  594.             FillShape(minx, maxx-minx);
  595.         end;
  596.     end;
  597.  
  598. {$IFDEF DEBUG}
  599.     SetRGB(0,0,0,0);
  600.     while KeyHit[26] do ; {Hit 'P' to pause}
  601. {$ENDIF}
  602. end;
  603.  
  604.  
  605. begin
  606.     OpenScreen;
  607.     InitDemo;
  608.     SetAllInterrupts;
  609.     repeat RunOnce until Key='e';
  610.     RestoreAllInterrupts;
  611.     UninitDemo;
  612.     CloseScreen;
  613. end.
  614.